Skip to content

feat: star and save commits from the API - #550

Merged
xHeaven merged 2 commits into
dev-null-sh:productionfrom
simonhamp:feat/api-stars-and-saves
Oct 19, 2026
Merged

xHeaven merged 2 commits into
dev-null-sh:productionfrom
simonhamp:feat/api-stars-and-saves

Conversation

@simonhamp

@simonhamp simonhamp commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Lets the mobile app star and save commits, and list the user's saved commits. It follows #130, which added the signed API. This is one of a few small PRs for the endpoints the app (NativePHP/dev-null-app) uses on top of it.

Endpoints

All of them take signed requests only.

Request Answer
POST /api/v1/commits/{id}/star 200 with the commit as GET /api/v1/commits/{id} shows it, with the new stars_count and starred
DELETE /api/v1/commits/{id}/star The same
PUT /api/v1/commits/{id}/bookmark 200 with the commit, with the new is_saved
DELETE /api/v1/commits/{id}/bookmark The same
GET /api/v1/saved The user's saved commits, last saved first, 20 a page with a cursor

Starring uses the web's CreateCommitStar and DeleteCommitStar, so the author gets the same grouped notification, and starring twice or unstarring something that isn't starred is fine. Starring your own commit is a 403 with the web's message.

Saving uses the web's CreateBookmark and DeleteBookmark with the same rules. Saving is a PUT because saving twice keeps one save.

A commit the user may not see, including one across a block, or a deleted one, is a 404 for all four writes, the same as GET /api/v1/commits/{id}. Stars and saves keep the web's limits of 60 a minute each, answered with rate_limited.

GET /api/v1/saved goes through the web's SavedCommitsQuery. Saved replies come with the parent the user may see, or its tombstone, and every saved commit has the reply preview the web shows. Commits across a block drop out of the list, as on the web.

Worth checking

The web lets anyone unstar any commit, and answers 403 for a commit they can't see. The API answers with the commit, so here unstarring needs a commit the user may see, and one they can't see is a 404.

The Pastéis PR (#557) adds pasteis_count to every signed commit. Whichever of the two merges second needs 'pasteis_count' => 0 added to the saved commit's fields in BookmarkControllerTest.

Testing

Everything CI runs passes on this branch locally: Pint, Rector, the JS lint, PHPStan, tsc, type coverage, and all 2,997 tests at 100% coverage.

The app's star button and its Saved tab (NativePHP/dev-null-app#5) have been running against these endpoints on a phone.

Adds POST and DELETE /api/v1/commits/{commit}/star for signed requests. They use the web's CreateCommitStar and DeleteCommitStar actions, so starring twice or unstarring a commit that isn't starred is fine, and the author gets the same grouped star notification. Both answer with the commit as GET /api/v1/commits/{commit} shows it, with the new stars_count and starred.

The user may star any commit they may see but their own, like on the web, which answers their own with a 403 and the web's message. A commit they may not see, including one across a block, or a deleted one, is a 404 like on GET /api/v1/commits/{commit}. The web answers 403 there and lets anyone unstar any commit, but the API sends the commit back, so unstarring needs a commit the user may see too. Muting someone doesn't stop starring their commits, as on the web.

Starring and unstarring share the web's limit of 60 a minute, answered with rate_limited like the API's other limits.
Adds PUT and DELETE /api/v1/commits/{commit}/bookmark and GET /api/v1/saved for signed requests. Saving uses the web's CreateBookmark and DeleteBookmark actions with the same rules: the user may save any commit they may see, saving twice keeps one save, and unsaving something that isn't saved is fine. A commit they may not see, or a deleted one, is a 404. Both answer with the commit as GET /api/v1/commits/{commit} shows it, with the new is_saved.

GET /api/v1/saved lists the user's own saves through the web's SavedCommitsQuery, last saved first, 20 at a time with a cursor like the other lists. Saved replies come with the parent the user may see, or its tombstone, and every saved commit with the reply preview the web shows. Commits across a block drop out of the list, as on the web.

Saving and unsaving share the web's limit of 60 a minute, answered with rate_limited.
Copilot AI balanced review requested due to automatic review settings October 19, 2026 06:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@simonhamp
simonhamp marked this pull request as ready for review October 19, 2026 08:47
@xHeaven
xHeaven merged commit debb75e into dev-null-sh:production Oct 19, 2026
6 checks passed
@simonhamp
simonhamp deleted the feat/api-stars-and-saves branch October 19, 2026 23:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants